import React, { useLayoutEffect } from 'react';
import PropTypes from 'prop-types';
import cn from 'classnames';
import './Topology.less';
import { Icon } from 'antd';

const elementIsShown = element => element.offsetWidth > 0 && element.offsetHeight > 0;

const Topology = ({
    data,
    renderLabel,
    labelKey,
    childrenKey,
    subChildrenKey,
    renderSubChildren,
    className,
    customItemClass,
    isGroup,
    ...rest
}) => {
    const computeStyle = () => {
        const labels = document.querySelectorAll('.topology-label');
        const lastChildrens = document.querySelectorAll('.topology-children-is-employee');
        // 最大距离右侧距离
        // const maxRightLength = 0;
        // 最小距离左侧距离
        // const minLeftLength = 10000;
        labels.forEach(label => {
            const labelWrap = label.querySelector('.topology-label-wrap');
            // const children = label.nextElementSibling;
            // const chidlrenBound = children.getBoundingClientRect();
            const subChildren = labelWrap.querySelector('.topology-sub-children');

            if (subChildren) {
                const item = subChildren.parentElement.parentElement.parentElement;
                // const isLastItem = !item.nextElementSibling;
                if (elementIsShown(subChildren)) {
                    const width = subChildren.getBoundingClientRect().right - labelWrap.getBoundingClientRect().right;
                    if (!item.classList.contains('topology-item-only-children')) {
                        item.setAttribute('style', `padding-right: ${width < 12 ? '12' : width}px!important`);
                    }
                    label.style.minHeight = `${subChildren.offsetHeight}px`;
                } else {
                    item.setAttribute('style', 'padding-right: 12px');
                    label.style.minHeight = 'auto';
                }
            }

            // 判断最大左侧和右侧距离
            // if (labelWrap) {
            //     const {
            //         left,
            //         right
            //     } = labelWrap.getBoundingClientRect();
            //     if (
            //         left - topology.getBoundingClientRect().left <
            //         minLeftLength
            //     ) {
            //         minLeftLength =
            //             left - topology.getBoundingClientRect().left;
            //     }
            //     if (
            //         right - topology.getBoundingClientRect().right >
            //         maxRightLength
            //     ) {
            //         maxRightLength =
            //             right - topology.getBoundingClientRect().right;
            //     }
            // }

            // 上下对齐
            if (labelWrap) {
                const topologyChildren = label.nextElementSibling;
                const topologyLevel = topologyChildren ? topologyChildren.firstElementChild : null;
                const topologyItems = topologyLevel
                    ? Array.from(topologyLevel.childNodes).filter(node => node.classList.contains('topology-item'))
                    : [];
                const firstTopologyItem = topologyItems[0];
                const lastTopologyItem = topologyItems[topologyItems.length - 1];

                if (firstTopologyItem && lastTopologyItem) {
                    // const one = firstTopologyItem.childNodes[0].querySelector(
                    //     '.topology-label-wrap'
                    // );
                    // const two = lastTopologyItem.childNodes[0].querySelector(
                    //     '.topology-label-wrap'
                    // );
                    // const {
                    //     width: oneWidth,
                    //     right: oneRight
                    // } = one.getBoundingClientRect();
                    // const {
                    //     width: twoWidth,
                    //     right: twoRight
                    // } = two.getBoundingClientRect();
                    // const {
                    //     width: threeWidth,
                    //     right: threeRight
                    // } = topologyChildren.getBoundingClientRect();
                    // const relative =
                    //     twoRight / 2 -
                    //     twoWidth / 4 +
                    //     oneRight / 2 -
                    //     oneWidth / 4 -
                    //     threeRight +
                    //     threeWidth / 2;
                    // 如果仅存在一级菜单，则不移动
                    // topologyChildren.style.left = `-${relative}px`;
                    // 第一级children不移动，保证第一级在最中间
                    // if (
                    //     !topologyChildren.parentElement.parentElement.classList.contains(
                    //         'topology-level-1'
                    //     )
                    // ) {
                    //     topologyChildren.parentElement.style.left = `${relative}px`;
                    // }
                    // const prevChildren =
                    //     topologyChildren.parentElement.parentElement
                    //         .parentElement;
                    // prevChildren.style.left = `${parseInt(
                    //     prevChildren.style.left
                    // ) -
                    //     relative / 2}px`;
                }
            }
            // 计算下面竖线高度
            const bottomLine = label.querySelector('.topology-label-bottom-line');
            if (bottomLine) {
                bottomLine.style.height = `${label.offsetHeight - labelWrap.offsetHeight + 31}px`;
            }
            //
            // // 计算 label-wrap，防止多了 topology-sub-children 导致上下不对齐
            // const subChildren = label.querySelector('.topology-sub-children');
            // if (subChildren) {
            //     labelWrap.style.marginLeft = `${window.parseInt(
            //         subChildren.offsetWidth
            //     )}px`;
            // }
        });

        lastChildrens.forEach(item => {
            const children = item.querySelector('.topology-children');
            const label = item.querySelector('.topology-label');

            if (children && label) {
                // item.style.minWidth = `${window.parseInt(label.offsetWidth) / 2 + window.parseInt(children.offsetWidth)}px`;
            }
        });

        // // 计算整体宽度，并默认横向滚动到一半
        // if (minLeftLength < 0) {
        //     topology.style.marginLeft = `${-minLeftLength}px`;
        // }
        // topology.style.minWidth = `${maxRightLength - minLeftLength}px`;
        // console.info('>>>', topology.parentElement.scrollWidth);
        // topology.parentElement.scrollLeft = topology.parentElement.scrollWidth / 2;
        //
        // // 画 topology-level 上面的横向
        // const levels = document.querySelectorAll('.topology-level');
        //
        // levels.forEach(level => {
        //     if (level.hasChildNodes()) {
        //         const children = level.childNodes;
        //         const topLine = Array.from(children).filter(node =>
        //             node.classList.contains('topology-level-top-line')
        //         );
        //
        //         const items = Array.from(children).filter(node =>
        //             node.classList.contains('topology-item')
        //         );
        //         const firstItem = items[0];
        //         const lastItem = items[items.length - 1];
        //         const {
        //             right: firstItemRight,
        //             width: firstItemWidth
        //         } = firstItem.getBoundingClientRect();
        //         const {
        //             right: lastItemRight,
        //             width: lastItemWidth
        //         } = lastItem.getBoundingClientRect();
        //         // TODO why 6
        //         if (topLine[0]) {
        //             topLine[0].style.width = `${lastItemRight -
        //             lastItemWidth / 2 -
        //             (firstItemRight - firstItemWidth / 2) +
        //             12}px`;
        //             topLine[0].style.right = `${lastItemWidth / 2 - 12}px`;
        //         }
        //     }
        // });
        // const rightChildren = document.querySelectorAll('.topology-sub-children');
        //
        // rightChildren.forEach(children => {
        //     if (elementIsShown(children)) {
        //         const childrenBound = children.getBoundingClientRect();
        //         const label = children.parentElement.parentElement.parentElement;
        //         console.info('label:', label);
        //         const labelBound = label.getBoundingClientRect();
        //         label.style.padding = `0 ${children.offsetWidth}px!important`;
        //     }
        // });
    };
    const handleBottomClick = e => {
        const item = e.target.parentElement.parentElement.parentElement.parentElement.parentElement;
        if (item.classList.contains('topology-item-expanded')) {
            item.classList.remove('topology-item-expanded');
        } else {
            item.classList.add('topology-item-expanded');
        }
        computeStyle();
    };
    const handleRightClick = e => {
        const item = e.target.parentElement.parentElement.parentElement.parentElement.parentElement;
        if (item.classList.contains('topology-item-r-collapsed')) {
            item.classList.remove('topology-item-r-collapsed');
        } else {
            item.classList.add('topology-item-r-collapsed');
        }
        computeStyle();
    };
    const render = (tree, level, parentNode) => (
        <div className={cn('topology-level', `topology-level-${level}`)}>
            {tree.map((item, index) => {
                const resultLabel = typeof labelKey === 'function' ? labelKey(item) : item[labelKey];
                const resultChildren =
                    typeof childrenKey === 'function' ? childrenKey(item, parentNode) : item[childrenKey];
                const resultSubChildren =
                    typeof subChildrenKey === 'function' ? subChildrenKey(item) : item[subChildrenKey];
                const hasChildren = resultChildren && resultChildren.length > 0;
                const hasSubChildren = resultSubChildren && resultSubChildren.length > 0;
                return (
                    <div
                        className={cn(
                            'topology-item',
                            {
                                'topology-item-has-children': hasChildren,
                                'topology-item-has-sub-children': hasSubChildren,
                                'topology-item-only-children': tree.length === 1,
                                'topology-item-collapsed': true,
                                // 默认展开到一级部门，区域公司不显示
                                // TODO 先默认写死
                                'topology-item-expanded': isGroup
                                    ? item.managerPostName === '董事长' || item.managerPostName === 'CEO'
                                    : level === 1,
                                'topology-item-r-expanded': true,
                                'topology-item-r-collapsed': isGroup
                                    ? item.managerPostName !== 'CEO' && item.managerPostName !== '董事长'
                                    : level !== 1,
                                'topology-item-is-group':
                                    item.managerPostName === 'CEO' || item.managerPostName === '董事长',
                                'topology-item-is-company': item.cdType === 0,
                                'topology-children-is-employee': hasChildren && resultChildren[0].employeeName,
                                'topology-has-children-subchildren': hasChildren && hasSubChildren
                            },
                            customItemClass(item)
                        )}
                        key={item.id}
                    >
                        <div className="topology-label">
                            {index === 0 && <div className="topology-cover-left-line" />}
                            {index === tree.length - 1 && <div className="topology-cover-right-line" />}
                            <div className="topology-label-wrap">
                                {renderLabel ? renderLabel(item) : resultLabel}
                                {hasChildren && (
                                    <Icon
                                        className="topology-btn topology-plus-btn"
                                        title="展开"
                                        onClick={handleBottomClick}
                                        type="plus-circle"
                                        theme="twoTone"
                                        twoToneColor="#52c41a"
                                    />
                                )}
                                {hasChildren && (
                                    <Icon
                                        className="topology-btn topology-minus-btn"
                                        title="收起"
                                        onClick={handleBottomClick}
                                        type="minus-circle"
                                        theme="twoTone"
                                        twoToneColor="#52c41a"
                                    />
                                )}
                                {hasSubChildren && (
                                    <Icon
                                        className="topology-right-btn topology-right-plus-btn"
                                        title="展开"
                                        onClick={handleRightClick}
                                        type="plus-circle"
                                        theme="twoTone"
                                        twoToneColor="#52c41a"
                                    />
                                )}
                                {hasSubChildren && (
                                    <Icon
                                        className="topology-right-btn topology-right-minus-btn"
                                        title="收起"
                                        onClick={handleRightClick}
                                        type="minus-circle"
                                        theme="twoTone"
                                        twoToneColor="#52c41a"
                                    />
                                )}
                                {hasSubChildren && (
                                    <div className="topology-sub-children">
                                        {resultSubChildren.map(newItem => (
                                            <div key={newItem.id} className="topology-sub-item">
                                                {renderSubChildren && renderSubChildren(newItem)}
                                                {!renderSubChildren &&
                                                    (typeof labelKey === 'function'
                                                        ? labelKey(newItem)
                                                        : newItem[labelKey])}
                                            </div>
                                        ))}
                                        <div className="topology-sub-children-left-line" />
                                    </div>
                                )}
                            </div>
                            {hasChildren && <div className="topology-label-bottom-line" />}
                        </div>
                        {hasChildren && (
                            <div className="topology-children">{render(resultChildren, level + 1, item)}</div>
                        )}
                    </div>
                );
            })}
            {/* {tree.length > 1 && <div className="topology-level-top-line" />} */}
        </div>
    );
    useLayoutEffect(() => {
        const topology = document.querySelector('.topology');
        computeStyle();

        // 默认定位到中间位置
        topology.parentElement.scrollLeft = topology.parentElement.scrollWidth / 2 - topology.offsetWidth / 2;
    });
    return (
        <div className={cn('topology', className)} {...rest}>
            {render(data, 1)}
        </div>
    );
};

Topology.propTypes = {
    data: PropTypes.array,
    renderLabel: PropTypes.func,
    labelKey: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
    childrenKey: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
    subChildrenKey: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
    renderSubChildren: PropTypes.func,
    customItemClass: PropTypes.func,
    isGroup: PropTypes.bool,
    inner: PropTypes.bool
};

Topology.defaultProps = {
    data: [],
    renderLabel: undefined,
    labelKey: 'label',
    childrenKey: 'children',
    subChildrenKey: 'subChildren',
    renderSubChildren: undefined,
    isGroup: false,
    customItemClass: () => '',
    inner: false
};

export default Topology;
